﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using SharedGenomics.Workbench.Core;
using SharedGenomics.Workbench.Tests.TestObjects;

namespace SharedGenomics.Workbench.Tests.Core
{
    [TestClass]
    public class CachePresenterInitialisationStageTests
    {
        private PresenterInitialisationContext context;
        private CachePresenterInitialisationStage stage;

        [TestInitialize]
        public void Setup()
        {
            this.context = new PresenterInitialisationContext();
            this.stage = new CachePresenterInitialisationStage();
        }

        [TestMethod]
        public void ShouldNotReturnFromCacheFirst()
        {
            this.context.AddToCache = true;
            Assert.IsTrue(this.stage.Initialise(context));
        }

        [TestMethod]
        public void ShouldNotReturnFromCacheEver()
        {
            this.context.AddToCache = false;
            this.context.Current = new StubPresenter();

            this.stage.PostInitialise(context);

            this.context.Current = null;

            //stage should not prevent the chain from continuing since it should not have cached the presenter on the context previously
            Assert.IsTrue(this.stage.Initialise(context));
            Assert.IsNull(this.context.Current);
        }

        [TestMethod]
        public void ShouldNotReturnIfPresenterTypeNull()
        {
            Assert.IsTrue(this.stage.Initialise(this.context));
        }

        [TestMethod]
        public void ShouldReturnFromCache()
        {
            this.context.AddToCache = true;
            var presenter = new StubPresenter();
            this.context.Current = presenter;
            this.context.PresenterType = typeof(StubPresenter);

            this.stage.PostInitialise(context);

            //next call to initialse should set the presenter on the context and short-circuit the chain (i.e. return false)
            this.context.Current = null;
            Assert.IsFalse(this.stage.Initialise(context));
            Assert.AreSame(presenter, context.Current);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ShouldThrowIfContextNull()
        {
            this.stage.Initialise(null);
        }
    }
}
